package com.block.risk.service.type;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.block.common.service.LogFactory;
import com.block.db.entity.MemberExtInfo;
import com.block.db.entity.RiskConfigInfo;
import com.block.db.entity.RiskResultInfo;
import com.block.db.mapper.RiskConfigInfoMapper;
import com.block.db.mapper.RiskResultInfoMapper;
import com.block.risk.model.param.RiskControlParam;
import com.block.risk.model.result.RiskControlResult;
import com.block.risk.model.result.RiskJudgeResult;
import com.block.risk.service.IRiskResultInfoService;
import com.block.risk.service.IRiskService;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

@Service
public class YujuRiskService implements IRiskService {

    private static Logger log = LogFactory.getCommLog();

    private static String CONFIG_ID_TANZHEN_C = "1";
    private static String CONFIG_ID_QUANJING = "2";

    @Autowired
    IRiskResultInfoService riskResultInfoService;
    @Resource
    RiskResultInfoMapper riskResultInfoMapper;
    @Resource
    RiskConfigInfoMapper riskConfigInfoMapper;

    @Override
    public RiskControlResult riskHandlerExec(RiskControlParam riskParamInfo) {

        RiskControlResult controlResult = new RiskControlResult();
        controlResult.setSuccess(false);

        MemberExtInfo memberExtInfo = riskParamInfo.getMemberExtInfo();
        if (StrUtil.hasEmpty(memberExtInfo.getUsername(), memberExtInfo.getMobile(), memberExtInfo.getIdCard())){
            controlResult.setMessage("三要素信息不全");
            return controlResult;
        }

        RiskResultInfo riskResultInfoQuanJing =  riskResultInfoMapper.getEntityByConfigIdAndUid(CONFIG_ID_QUANJING, memberExtInfo.getUid());
        if (ObjectUtil.isEmpty(riskResultInfoQuanJing)){
            // 查到结果
            riskResultInfoQuanJing  = this.queryQuanJingResult(memberExtInfo, riskParamInfo);
            if (ObjectUtil.isEmpty(riskResultInfoQuanJing)){
                controlResult.setMessage("全景查询结果为空");
                return controlResult;
            }
        }

        if (!ObjectUtil.equals(Integer.valueOf(1), riskResultInfoQuanJing.getStatus())){
            controlResult.setMessage(riskResultInfoQuanJing.getMessage());
            return controlResult;
        }

        RiskResultInfo riskResultInfoTanZhen =  riskResultInfoMapper.getEntityByConfigIdAndUid(CONFIG_ID_TANZHEN_C, memberExtInfo.getUid());
        if (ObjectUtil.isEmpty(riskResultInfoTanZhen)){
            // 查到结果
            riskResultInfoTanZhen  = this.queryTanZhenCResult(memberExtInfo, riskParamInfo);
            if (ObjectUtil.isEmpty(riskResultInfoTanZhen)){
                controlResult.setMessage("探针C查询结果为空");
                return controlResult;
            }
        }

        if (!ObjectUtil.equals(Integer.valueOf(1), riskResultInfoTanZhen.getStatus())){
            controlResult.setMessage(riskResultInfoTanZhen.getMessage());
            return controlResult;
        }

        controlResult.setSuccess(true);
        controlResult.setMessage("河北钰聚风控通过");
        return controlResult;
    }

    private RiskResultInfo queryTanZhenCResult(MemberExtInfo memberExtInfo, RiskControlParam riskParamInfo){

        RiskConfigInfo riskConfigInfo = riskConfigInfoMapper.selectById(CONFIG_ID_TANZHEN_C);
        // 查询该数据的结果

        String requestUrl = riskConfigInfo.getRequestUrl();

        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("idcard", memberExtInfo.getIdCard());
        paramMap.put("mobile", memberExtInfo.getMobile());
        paramMap.put("name", memberExtInfo.getUsername());

        Map<String, String> headerMap = new HashMap<>();
        headerMap.put("appId", riskConfigInfo.getAppKey());
        headerMap.put("appKey", riskConfigInfo.getAppSecret());

        String response = HttpUtil.createPost(requestUrl)
                .headerMap(headerMap, true)
                .body(JSON.toJSONString(paramMap))
                .execute().body();
        log.info("【河北珏聚风控】【风控数据查询】探针【requestUrl】{}【paramMap】{}【response】{}", requestUrl, JSON.toJSONString(paramMap), response);

        JSONObject jsonObject = JSON.parseObject(response);
        String code = jsonObject.getString("code");
        String data = jsonObject.getString("data");
        String message = jsonObject.getString("message");

        RiskResultInfo riskResultInfo = new RiskResultInfo();
        riskResultInfo.setDataId(riskParamInfo.getDataId());
        riskResultInfo.setDataType(riskParamInfo.getDataType());

        riskResultInfo.setConfigId(riskConfigInfo.getId());
        riskResultInfo.setUid(memberExtInfo.getUid());
        riskResultInfo.setUsername(memberExtInfo.getUsername());
        riskResultInfo.setMobile(memberExtInfo.getMobile());
        riskResultInfo.setIdcard(memberExtInfo.getIdCard());
        riskResultInfo.setCode(code);
        riskResultInfo.setMessage(message);
        riskResultInfo.setResult(data);
        riskResultInfo.setResultInfo(response);

        // 风控结果判断
        RiskJudgeResult riskJudgeResult = this.riskControlTanZhenC(riskResultInfo);
        riskResultInfo.setStatus(riskJudgeResult.isPass()?1:0);
        riskResultInfo.setMessage(riskJudgeResult.getResult());

        boolean save = riskResultInfoService.save(riskResultInfo);
        if (!save){
            return null;
        }
        return riskResultInfo;
    }


    private RiskResultInfo queryQuanJingResult(MemberExtInfo memberExtInfo, RiskControlParam riskParamInfo){

        RiskConfigInfo riskConfigInfo = riskConfigInfoMapper.selectById(CONFIG_ID_QUANJING);
        // 查询该数据的结果

        String requestUrl = riskConfigInfo.getRequestUrl();

        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("idcard", memberExtInfo.getIdCard());
        paramMap.put("mobile", memberExtInfo.getMobile());
        paramMap.put("name", memberExtInfo.getUsername());

        Map<String, String> headerMap = new HashMap<>();
        headerMap.put("appId", riskConfigInfo.getAppKey());
        headerMap.put("appKey", riskConfigInfo.getAppSecret());

        String response = HttpUtil.createPost(requestUrl)
                .headerMap(headerMap, true)
                .body(JSON.toJSONString(paramMap))
                .execute().body();
        log.info("【河北珏聚风控】【风控数据查询】全景【requestUrl】{}【paramMap】{}【response】{}", requestUrl, JSON.toJSONString(paramMap), response);

        JSONObject jsonObject = JSON.parseObject(response);
        String code = jsonObject.getString("code");
        String data = jsonObject.getString("data");
        String message = jsonObject.getString("message");

        RiskResultInfo riskResultInfo = new RiskResultInfo();
        riskResultInfo.setConfigId(riskConfigInfo.getId());
        riskResultInfo.setDataId(riskParamInfo.getDataId());
        riskResultInfo.setDataType(riskParamInfo.getDataType());

        riskResultInfo.setUid(memberExtInfo.getUid());
        riskResultInfo.setUsername(memberExtInfo.getUsername());
        riskResultInfo.setMobile(memberExtInfo.getMobile());
        riskResultInfo.setIdcard(memberExtInfo.getIdCard());
        riskResultInfo.setCode(code);
        riskResultInfo.setMessage(message);
        riskResultInfo.setResult(data);
        riskResultInfo.setResultInfo(response);

        // 风控结果判断
        RiskJudgeResult riskJudgeResult = this.riskControlQuanJing(riskResultInfo);
        riskResultInfo.setStatus(riskJudgeResult.isPass()?1:0);
        riskResultInfo.setMessage(riskJudgeResult.getResult());

        boolean save = riskResultInfoService.save(riskResultInfo);
        if (!save){
            return null;
        }
        return riskResultInfo;
    }


    /**
     * 探针风
     * @param riskResultInfo
     * @return
     */
    private RiskJudgeResult riskControlTanZhenC(RiskResultInfo riskResultInfo){
        RiskJudgeResult riskJudgeResult = new RiskJudgeResult();
        riskJudgeResult.setPass(false);

        String code = riskResultInfo.getCode();
        if (!StrUtil.equals(code, "20000")){
            riskJudgeResult.setResult(riskResultInfo.getMessage());
            return riskJudgeResult;
        }

        String resultInfo = riskResultInfo.getResult();
        try {
            JSONObject jsonObject = JSON.parseObject(resultInfo);
            String resultCode = jsonObject.getString("result_code");
            if (StrUtil.equals(resultCode, "2") || StrUtil.equals(resultCode, "3") || StrUtil.equals(resultCode, "4")){
                riskJudgeResult.setPass(true);
                riskJudgeResult.setResult("探针C风控通过");
                return riskJudgeResult;
            }
            riskJudgeResult.setResult("探针C风控未通过；resultCode："+resultCode);
        }catch (JSONException exception){
            riskJudgeResult.setResult(riskResultInfo.getResult());
        }
        return riskJudgeResult;
    }

    private RiskJudgeResult riskControlQuanJing(RiskResultInfo riskResultInfo){
        RiskJudgeResult riskJudgeResult = new RiskJudgeResult();
        riskJudgeResult.setPass(false);

        String code = riskResultInfo.getCode();
        if (!StrUtil.equals(code, "20000")){
            riskJudgeResult.setResult(riskResultInfo.getMessage());
            return riskJudgeResult;
        }

        String resultInfo = riskResultInfo.getResult();
        try {
            JSONObject jsonObject = JSON.parseObject(resultInfo);

            JSONObject currentReportDetail = jsonObject.getJSONObject("current_report_detail");
            JSONObject behaviorReportDetail = jsonObject.getJSONObject("behavior_report_detail");
            JSONObject applyReportDetail = jsonObject.getJSONObject("apply_report_detail");

            if (ObjectUtil.isEmpty(behaviorReportDetail)){
                riskJudgeResult.setResult("行为数据结果为空；【behavior_report_detail】");
                return riskJudgeResult;
            }

            // 订单结清笔数8笔以上
            // 贷款已结清订单数
            String numberSettle = behaviorReportDetail.getString("B22170052");
            if (Integer.valueOf(numberSettle) < 8){
                riskJudgeResult.setResult(StrUtil.format("订单结清笔数8笔以上不通过；【{}】", numberSettle));
                return riskJudgeResult;
            }

            // 订单比例90以上
            // 正常还款订单数占贷款总订单数比例
            String numberRate = behaviorReportDetail.getString("B22170034");
            numberRate = numberRate.replace("%", "");
            if (Integer.valueOf(numberRate) < 90){
                riskJudgeResult.setResult(StrUtil.format("订单比例90以上不通过；【{}】", numberRate));
                return riskJudgeResult;
            }

            // 近6个月逾期M0 = 0
            String numberSixM0 = behaviorReportDetail.getString("B22170025");
            if (Integer.valueOf(numberSixM0) > 0){
                riskJudgeResult.setResult(StrUtil.format("近6个月逾期M0不通过；【{}】", numberSixM0));
                return riskJudgeResult;
            }

            // 近一个月贷款机构放款笔数1笔以上
            String numberLoanOne = behaviorReportDetail.getString("B22170002");
            if (Integer.valueOf(numberLoanOne) == 0){
                riskJudgeResult.setResult(StrUtil.format("近一个月贷款机构放款笔数1笔以上不通过；【{}】", numberLoanOne));
                return riskJudgeResult;
            }

            // 成功扣款笔数大于失败笔数.
            String numberSuccess = behaviorReportDetail.getString("B22170045");
            String numberFailed = behaviorReportDetail.getString("B22170035");
            if (Integer.valueOf(numberFailed) >= Integer.valueOf(numberSuccess)){
                riskJudgeResult.setResult(StrUtil.format("成功扣款笔数大于失败笔数不通过；成功扣款笔数【{}】失败笔数【{}】", numberSuccess, numberFailed ));
                return riskJudgeResult;
            }

            riskJudgeResult.setPass(true);
            riskJudgeResult.setResult("全景分控通过");
            return riskJudgeResult;
        }catch (JSONException exception){
            exception.printStackTrace();
            riskJudgeResult.setResult(riskResultInfo.getResult());
        }
        return riskJudgeResult;
    }

}
